﻿// 2023/3/13: 首个版本
// 2023/3/20: 完善buttonAdd禁用逻辑

using System;
using System.Collections.Generic;
using System.Linq;
using ASEva;
using ASEva.Samples;
using ASEva.UIEto;
using Eto.Forms;
using Eto.Drawing;

namespace CommonSource
{
    class SignalAdder : DialogPanel
    {
        public SignalAdder(List<String> addedSignalIDs, SelectSignalHandler handler, CommonImage icon = null)
        {
            this.addedSignalIDs = addedSignalIDs;
            this.handler = handler;

            if (icon != null) Icon = new Icon(1, icon.ToEtoBitmap());
            Title = chinese ? "信号添加" : "Add signal";
            SetFixMode(440, 570, true);

            var mainLayout = this.SetContentAsColumnLayout();
            var searchBox = mainLayout.AddControl(new SearchBox()) as SearchBox;
            treeView = mainLayout.AddControl(new SimpleTreeView(), true) as SimpleTreeView;
            var buttonLayout = mainLayout.AddRowLayout();
            buttonLayout.AddSpace();
            buttonAdd = buttonLayout.AddButton(chinese ? "添加" : "Add", false, 100);

            buttonAdd.Enabled = false;

            noAvailables = !rebuildTreeView(Agency.GetSignalTree(), "");
            if (noAvailables)
            {
                searchBox.Enabled = false;
                addNoAvailables();
            }

            searchBox.TextChanged += delegate
            {
                noAvailables = !rebuildTreeView(Agency.GetSignalTree(), searchBox.Text.ToLower());
                if (noAvailables)
                {
                    buttonAdd.Enabled = false;
                    addNoAvailables();
                }
            };

            buttonAdd.Click += delegate
            {
                addSignal();
            };

            treeView.SelectedItemChanged += delegate
            {
                if (noAvailables) return;

                bool enabled = false;
                var key = treeView.GetSelectedKey();
                if (key != null && key is SignalTreeNode)
                {
                    var nodeType = (key as SignalTreeNode).Type;
                    enabled = (int)nodeType >= (int)SignalTreeNodeType.GeneralSignal;
                }
                buttonAdd.Enabled = enabled && !addButtonDisabled;
            };

            treeView.SelectedItemActivated += delegate
            {
                if (buttonAdd.Enabled)
                {
                    addSignal();
                }
                else
                {
                    var key = treeView.GetSelectedKey();
                    if (key != null && key is String) searchBox.Text = key as String + ".all";
                }
            };
        }

        private bool rebuildTreeView(SignalTreeNode[] tops, String key)
        {
            var topNodes = new List<SimpleTreeNode>();
            var itemAdded = false;
            bool keyValid = key.Length >= 2;

            foreach (var top in tops)
            {
                var topMatch = keyValid && (top.ID.ToLower().Contains(key) || top.Name.ToLower().Contains(key));

                var topNode = new SimpleTreeNode{ Key = top, Text = top.Name };
                var shouldAddTopNode = !keyValid || topMatch;

                foreach (var middle in top.Children)
                {
                    var middleMatch = keyValid && (middle.ID.ToLower().Contains(key) || middle.Name.ToLower().Contains(key));
                    var bottomAllMatch = keyValid && (key == middle.ID.ToLower() + ".all");

                    var middleNode = new SimpleTreeNode{ Key = middle, Text = middle.Name };
                    bool shouldAddMiddleNode = !keyValid || topMatch || middleMatch;

                    String multiplexedTarget = null;
                    foreach (var bottom in middle.Children)
                    {
                        var bottomMatch = keyValid && (bottom.ID.ToLower().Contains(key) || bottom.Name.ToLower().Contains(key));
                        var isAdded = (int)bottom.Type >= (int)SignalTreeNodeType.GeneralSignal && addedSignalIDs.Contains(bottom.ID);

                        SimpleTreeNode bottomNode = null;
                        if (bottom.Type == SignalTreeNodeType.MultiplexedBusSignal)
                        {
                            if (bottomAllMatch) bottomNode = new SimpleTreeNode{ Key = bottom, Text = bottom.Name, TextColor = isAdded ? Colors.Green : Colors.Blue };
                            else if (shouldAddMiddleNode) multiplexedTarget = middle.ID;
                        }
                        else
                        {
                            var shouldAddBottomNode = !keyValid || topMatch || middleMatch || bottomMatch || bottomAllMatch;
                            if (shouldAddBottomNode) bottomNode = new SimpleTreeNode{ Key = bottom, Text = bottom.Name, TextColor = isAdded ? Colors.Green : Colors.Blue };
                        }

                        if (bottomNode != null)
                        {
                            middleNode.ChildNodes.Add(bottomNode);
                            shouldAddMiddleNode = true;
                        }
                    }

                    if (multiplexedTarget != null)
                    {
                        var bottomNode = new SimpleTreeNode{ Key = multiplexedTarget, Text = chinese ? "多路复用信号..." : "Multiplexed signals ..." };
                        middleNode.ChildNodes.Add(bottomNode);
                        shouldAddMiddleNode = true;
                    }

                    if (shouldAddMiddleNode)
                    {
                        if (keyValid) middleNode.ChildNodesExpanded = true;
                        topNode.ChildNodes.Add(middleNode);
                        shouldAddTopNode = true;
                    }
                }

                if (shouldAddTopNode)
                {
                    if (keyValid) topNode.ChildNodesExpanded = true;
                    topNodes.Add(topNode);
                    itemAdded = true;
                }
            }

            treeView.SetModel(topNodes.ToArray(), true);

            return itemAdded;
        }

        private void addNoAvailables()
        {
            var topNode = new SimpleTreeNode{ Key = new object(), Text = chinese ? "(无可用)" : "(No availables)" };
            treeView.SetModel(new SimpleTreeNode[]{ topNode }, false);
        }

        private void addSignal()
        {
            var key = treeView.GetSelectedKey();
            var signalID = (key as SignalTreeNode).ID;
            if (!handler.SelectSignal(signalID))
            {
                addButtonDisabled = true;
            }
            addedSignalIDs.Add(signalID);

            var updateTask = new SimpleTreeNodeUpdateTask();
            updateTask.Key = key;
            updateTask.TextColor = Colors.Green;
            treeView.UpdateNodes(new SimpleTreeNodeUpdateTask[]{ updateTask });

            buttonAdd.Enabled = false;
        }

        private List<String> addedSignalIDs;
        private SelectSignalHandler handler;
        private bool addButtonDisabled;
        private bool noAvailables;
        private SimpleTreeView treeView;
        private Button buttonAdd;

        private bool chinese = Agency.GetAppLanguage() == "ch";
    }
}
